package agend.client.gui.utils;

import jade.gui.GuiEvent;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.GregorianCalendar;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

import myContacts.AddressBook;
import myContacts.AddressBookHandler;
import myContacts.Contact;
import myContacts.Link;
import myContacts.wrapper.ContactWrapper;
import GoogleServices.GoogleCalendarCalls;
import GoogleServices.GoogleContactCalls;

import agend.client.gui.utils.exceptions.ContactsOldExceptions;

import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

public class Broker extends Subject{

	private static final long GIORNO = 86400000;
	
	private static GoogleCalendarCalls calendarService;
	private static GoogleContactCalls contactService;

	private static AddressBookHandler addressBookHandler = new AddressBookHandler();
	
	private static String username;

	public static GoogleCalendarCalls getCalendarService() {
		return calendarService;
	}

	public static GoogleContactCalls getContactService() {
		return contactService;
	}

	public static void setGoogleCredentials(String username, String password) throws AuthenticationException 
	{
		calendarService = new GoogleCalendarCalls(username, password);
		contactService = new GoogleContactCalls(username, password);
	}


	/**
	 * Se esiste il file contacts.ct allora i contatti vengono letti da 
	 * quest' ultimo altrimenti li legge da google e li scrive su file
	 * 
	 * Se li legge da file ritorna true altrimenti ritorna false
	**/
	public static boolean getAllContact (String username) {

		Broker.username = username;
				
		try {
			addressBookHandler.setAddressBook(readContacts());
		} catch (Exception e) {

			syncContactFromGoogle();
			
		}
		return true;

	}

	public static void syncContactFromGoogle() {

		try {

			AddressBook addressBook = contactService.getAllContacts();
			loadImagesFromContacts(addressBook);
			addressBookHandler.setAddressBook(addressBook);

			GuiEvent syncEmailEvent = HandlerEvent.createSyncEmailEvent();
			HandlerView.getAgent().postGuiEvent(syncEmailEvent);

			//writeContacts();
			
			System.out.println("Leggo contatti");
			//addressBookHandler.getContacts();

		} catch (Exception e1) {
			JOptionPane.showMessageDialog(HandlerView.getFrame(), "Errore nel contattare Google", "Errore connessione", JOptionPane.ERROR_MESSAGE);
		}
	}

	/**
	 * Legge  i contatti dal file in precedenza serializzato contacts.ct
	 * @throws FileNotFoundException
	 */
	public static AddressBook readContacts() throws ContactsOldExceptions
	{
		try {
			FileInputStream fis = new FileInputStream("contacts/"+username+"_contacts.ct");

			ObjectInputStream ois = new ObjectInputStream(fis);
			AddressBook addressBook = (AddressBook) ois.readObject();

			GregorianCalendar gregorianCalendarOggi = new GregorianCalendar();
			
			long oggi = gregorianCalendarOggi.getTimeInMillis();
			long last = addressBook.getDataSerialization().getTimeInMillis();

			if(oggi-last<GIORNO*5)
				return addressBook;
			else
				throw new ContactsOldExceptions();

		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			//e1.printStackTrace();
			throw new ContactsOldExceptions();
		} 
		catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new ContactsOldExceptions();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new ContactsOldExceptions();
		}
	}

	/**
	 * Memorizza l' oggetto Serializzabile AddressBook all' interno 
	 * del file contacts.ct
	 */
	public static void writeContacts()
	{
		FileOutputStream fileOutputStream;

		try {

			fileOutputStream = new FileOutputStream("contacts/"+username+"_contacts.ct");
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
			addressBookHandler.getAddressBook().setDataSerialization(new GregorianCalendar());//Setto la data di serializzazione dell' oggetto

			objectOutputStream.writeObject(addressBookHandler.getAddressBook());
			System.out.println("SERIALIZZAIONE COMPLETATA");

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}    
	}


	public static List<Contact> getAddressBook() {
		return addressBookHandler.getContacts();
	}	

	public static  void loadImagesFromContacts(AddressBook addressBook) {

		for(Contact contact: addressBook.getContacts()){

			if(contact.getContactPhotoLink().getEtag() != null){

				Link link = contact.getContactPhotoLink();
				byte[] fotoBytes = null;

				try {

					com.google.gdata.data.Link googleLink = ContactWrapper.wrappMyLink(link);
					fotoBytes = getContactService().downloadPhoto(googleLink);
					contact.setPhoto(new ImageIcon(fotoBytes));

				} catch (ServiceException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
			else
				contact.setPhoto(null);

		}
	}

	public static AddressBookHandler getAddressBookHandler() {
		return addressBookHandler;
	}

	public static String getUsername() {
		return username;
	}

}
